const fetch = require('node-fetch');
// const { logger } = require('../utils/logger');
const { TIME_CONSTANT } = require('./constant');
const { HttpError, CustomError,HTTP_STATUS } = require('../error');

const request = async (method, url, reqData = null, headers = null) => {
  let content = {
    method: method,
    timeout: TIME_CONSTANT.GATEWAY_TIMEOUT
  }
  if (reqData) {
    content.body = JSON.stringify(reqData);
  }
  if (headers) {
    content.headers = headers;
  }

  try {
    const response = await fetch(url, content);
    let body = await response.text();
    if (response.status < 200 || response.status >= 300) {
      console.error(`HTTP Error Response ${response.status} ${response.statusText} body: ${body}`);
    }
    return body;
  } catch (e) {
    if (e instanceof SyntaxError) {
      throw new HttpError(`HTTP request unavailable ==> url: ${url}`, HTTP_STATUS.BAD_REQUEST);
    }
    if (e instanceof fetch.FetchError) {
      if (e.type === 'request-timeout') {
        throw new HttpError(`HTTP request timeout ==> url: ${url}`, HTTP_STATUS.REQUEST_TIMEOUT );
      }
    }
    throw new HttpError(`HTTP Error Response: ${e.message}`,HTTP_STATUS.NOT_ACCEPTABLE);
  }

};

const get = (url, headers=null) => {
  return request('GET', url, null, headers)
};
const post = (url, reqData = null, headers = null) => {
  return request('POST', url, reqData, headers)
};
const json = async (url, reqData = null, headers = null) => {
  const data =  await request('POST', url, reqData, headers)
  return JSON.parse(data)
};
const patch = (url, reqData = null, headers = null) => {
  return request('PATCH', url, reqData, headers)
};
const deleted = (url, headers = null) => {
  return request('DELETE', url, null, headers)
};

module.exports = {
  get,
  post,
  json,
  patch,
  deleted
}